#include "kdccompositejob.h"

KDCCompositeJob::KDCCompositeJob( QObject *parent )
	: KDCJob( parent )
{

}

KDCCompositeJob::~KDCCompositeJob()
{
	KJob *job;
	while( !p_jobs.isEmpty() )
	{
		job = p_jobs.last();
		removeSubjob( job );
		if ( job )
		{
			job->disconnect();
			job->deleteLater();
		}
	}
}

void KDCCompositeJob::start()
{
	subjobs().first()->start();
}

int KDCCompositeJob::count() const
{
	int size = 0;
	KDCJob *job;
	for ( int i=0; i<subjobs().size(); ++i )
	{
		job = static_cast<KDCJob*>( subjobs().at( i ) );
		size += job->count();
	}
	return size;
}

void KDCCompositeJob::addSubjob( KDCJob *job )
{
	p_jobs.append( job );
	makeConnections( job );
}

void KDCCompositeJob::insertSubjob( KDCJob *job, int size )
{
	p_jobs.insert( size, job );
	makeConnections( job );
}

void KDCCompositeJob::makeConnections( KJob *job )
{
	connect( job, SIGNAL( result( KJob * ) ), this, SLOT( slotResult( KJob * ) ) );
	connect( job, SIGNAL( infoMessage( KJob *, const QString&, const QString& ) ), this,
								SLOT( slotInfoMessage( KJob *, const QString&, const QString& ) ) );
	connect( job, SIGNAL( percent( KJob *, unsigned long ) ), this, SLOT( slotPercent( KJob *, unsigned long ) ) );

	setTotalAmount( KJob::Bytes, totalAmount( KJob::Bytes ) + job->totalAmount( KJob::Bytes ) );
}

void KDCCompositeJob::slotResult( KJob *job )
{
	if ( job->error() && !error() )
	{
		setError( job->error() );
		setErrorText( job->errorText() );
		emitResult();
	}
	removeSubjob( job );

	if ( hasSubjobs() )
		p_jobs.first()->start();
	else
	{
		if ( !endingMessage().isEmpty() )
			emit infoMessage( this, endingMessage() );
		emitResult();
	}
}

void KDCCompositeJob::slotInfoMessage( KJob *job, const QString &plain, const QString &rich )
{
	emit infoMessage( job, plain, rich );
}

bool KDCCompositeJob::removeSubjob( KJob *job )
{
	if ( job == 0 )
		return FALSE;
	job->disconnect();
	p_jobs.removeAll( job );
	return TRUE;
}

bool KDCCompositeJob::hasSubjobs()
{
	return !p_jobs.isEmpty();
}

const QList<KJob*>& KDCCompositeJob::subjobs() const
{
	return p_jobs;
}

void KDCCompositeJob::clearSubjobs()
{
	p_jobs.clear();
}

void KDCCompositeJob::slotPercent( KJob *job, unsigned long size )
{
	setProcessedAmount( KJob::Bytes, processedAmount( KJob::Bytes ) + qRound( size/100.0 * job->totalAmount( KJob::Bytes ) ) );
}
